package com.wiegand.util {
	import flash.display.DisplayObject;
	import flash.display.DisplayObjectContainer;
	import flash.geom.Matrix3D;

	/**
	 * @author gandy
	 */
	public class Sorter {
		
		public static function simpleZSort3DChildren( doc:DisplayObjectContainer, recurse:Boolean = true ) : void
		{
		 
		    //transforms from local to world oordinate frame
		    var transform:Matrix3D = doc.transform.getRelativeMatrix3D( doc.stage );
		 
		    var numChildren:int = doc.numChildren;
		 
		    //v = ( n * 3 )- (x,y,z) set for each child
		    var vLength:int = numChildren * 3;
		 
		    var vLocal:Vector.<Number> = new Vector.<Number>( vLength, true );
		    var vWorld:Vector.<Number> = new Vector.<Number>( vLength, true );
		 
		    //insertion point for child’s coordinates into state vector
		    var vIndex:int = 0;
		 
		    for( var i:int = 0; i <numChildren; i++ )
		    {
		 
		        var child:DisplayObject = doc.getChildAt( i );
		        if( recurse && child is DisplayObjectContainer ) simpleZSort3DChildren( DisplayObjectContainer( child ), true );
		 
		        vLocal[ vIndex ] = child.x;
		        vLocal[ vIndex + 1 ] = child.y;
		        vLocal[ vIndex + 2 ] = child.z;
		 
		        vIndex += 3;
		 
		    }
		 
		    //populates vWorld with children coordinates in world space
		    transform.transformVectors( vLocal, vWorld );
		 
		 
		 
		    //bubble sorts children along world z-axis
		    for( i = numChildren - 1; i > 0; i-- )
		    {
		 
		        var hasSwapped:Boolean = false;
		 
		        vIndex = 2;
		 
		        for( var j:int = 0; j < i; j++ )
		        {
		 
		            //z value at that index for each child
		            var z1:Number = vWorld[ vIndex ];
		 
		            vIndex += 3;
		 
		            var z2:Number = vWorld[ vIndex ];
		 
		            if( z2> z1 )
		            {
		 
		                //swap
		                doc.swapChildrenAt( j, j + 1 );
		 
		                //swap z values (don’t need to change x and y because they’re not used anymore)
		                vWorld[ vIndex - 3 ] = z2;
		                vWorld[ vIndex ] = z1;
		 
		                //mark as swapped
		                hasSwapped = true;
		 
		            }
		 
		        }
		 
		        //if there was no swap, we don’t need to iterate again
		        if( !hasSwapped ) return;
		 
		    }
		
		}
				
		
		
	}
}
